/*
 * ConnectionManager.hpp
 *
 *  Created on: Nov 21, 2014
 *      Author: toti
 */

#ifndef CONNECTIONMANAGER_HPP_
#define CONNECTIONMANAGER_HPP_

#include <sys/epoll.h>

#include <list>

#include <Misc/Config.hpp>
#include <Connectivity/EPoll.hpp>
#include <Connectivity/TCPServer.hpp>
#include <Connectivity/TCPClient.hpp>
#include <Connectivity/TCPConnection.hpp>
#include <Connectivity/PeerDiscovery.hpp>
#include <Network/LocalServer.hpp>
#include <Network/LocalClient.hpp>
#include <Network/MessagePackages/MessagePackage.hpp>
#include <Network/MessagePackages/ServerMessagePackage.hpp>
#include <Network/MessagePackages/ClientMessagePackage.hpp>
#include <Network/NetworkServer.hpp>
#include <Network/NetworkClient.hpp>
#include <UI/UserInterface.hpp>

class ConnectionManager{



private:


	Config *config;

	bool respondToDiscoveryRequests;

	/*
	 * Message lists
	 */
	std::list<MessagePackage*> *inboundMessagePackageList;
	std::list<MessagePackage*> *outboundMessagePackageList;

	/*
	 * Local nodes for working connections
	 */
	std::string parentAddress;
	std::string parentPort;

	LocalNode *parentLocalNode;
	TCPServer *localServerTcpServer;
	std::list<LocalNode*> *localClientList;
	std::list<LocalNode*> *localServerList;

	/*
	 * UI
	 */
	UserInterface *userInterface;

	/*
	 * Peer discovery
	 */
	PeerDiscovery *peerDiscovery;

	/*
	 * epoll stuff
	 */
	EPoll *epoll;

	void handlePeerDiscoveryRequest();
	void handlePeerDiscoveryResponse();

	void handleExistingLocalNodeError(LocalNode *localNode);

	void handleNewLocalServerConnection(TCPServer *tcpServer);

	void handleUserInterfaceData(LocalNode *localNode);
	void handleExistingLocalNodeConnection(LocalNode *localNode);

public:

	ConnectionManager(UserInterface *userInterface);

	void init();

	bool openParentServerConnection(std::string &port, std::string &address);

	void closeAllConnections();
	void closeServerListening();


	void handleInputData();
	void handleOutputData();

	void	setRespondToDiscoveryRequests(bool respond);
	void	setLocalParentServer(LocalNode *localNode);

	PeerDiscovery			*getPeerDiscovery();
	std::string 			&getParentAddress();
	std::string				&getParentPort();
	LocalNode 				*getUserInterface();
	LocalNode 				*getLocalParentServer();
	std::list<LocalNode*> 	*getLocalClientList();
	std::list<LocalNode*> 	*getLocalServerList();

	bool isMessagesAvailable();
	void pushOutboundMessagePackageList(MessagePackage *messagePackage);
	void pushInboundMessagePackageList(MessagePackage *messagePackage);
	MessagePackage *popInboundMessagePackageList();


};


#endif /* CONNECTIONMANAGER_HPP_ */
